﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace RDSEngine.WorkItems
{
    public class CmdAssistant
    {
        private CmdAssistant()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }

        private static CmdAssistant _cmd = null;

        public static CmdAssistant GetInstance()
        {
            return _cmd ?? (_cmd = new CmdAssistant());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public string RunCmd(string cmd, string args)
        {
            bool isShowMsg = true;//ConfigurationManager.AppSettings["ShowCommand"].ToString().ToLower() == "true";
            Process myProcess = new Process();
            //using (Process myProcess = new Process()) //创建进程对象  
            {
                //准备读出输出流和错误流
                string outputData = string.Empty;
                string errorData = string.Empty;
                try
                {
                    myProcess.StartInfo.UseShellExecute = false; //是否使用系统外壳程序启动  
                    myProcess.StartInfo.FileName = cmd;          //设定需要执行的命令
                    myProcess.StartInfo.CreateNoWindow = !isShowMsg;  //是否创建窗口 
                    myProcess.StartInfo.WindowStyle = isShowMsg ? System.Diagnostics.ProcessWindowStyle.Normal : System.Diagnostics.ProcessWindowStyle.Hidden;
                    myProcess.StartInfo.Arguments = args;
                    myProcess.StartInfo.RedirectStandardInput = false;   //是否重定向输入
                    myProcess.StartInfo.RedirectStandardError = !isShowMsg;    //重定向错误输出
                    //myProcess.StartInfo.RedirectStandardOutput = true; //重定向输出
                    //myProcess.EnableRaisingEvents = true;
                    //myProcess.Exited += myProcess_Exited;
                    myProcess.Start();

                    //StreamReader errorreader = myProcess.StandardError;
                    //myProcess.OutputDataReceived += (ss, ee) =>
                    //{
                    //    outputData += ee.Data;
                    //};
                    //myProcess.ErrorDataReceived += (ss, ee) =>
                    //{
                    //    errorData += ee.Data;
                    //};

                    myProcess.WaitForExit();
                    string result = "";
                    //string result = errorreader.ReadToEnd();
                    //string output = myProcess.StandardOutput.ReadToEnd();//读取进程的输出  

                    return string.IsNullOrEmpty(result) ? "" : "Err:" + result;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return ex.Message;
                }
            }
        }

        public string RunDosCmd(string cmd, string args)
        {
            string dosCmd = cmd + " " + args;
            Process myProcess = new Process(); //创建进程对象  
            try
            {
                myProcess.StartInfo.UseShellExecute = false; //是否使用系统外壳程序启动  
                myProcess.StartInfo.FileName = "cmd.exe"; //设定需要执行的命令
                myProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                myProcess.StartInfo.CreateNoWindow = true; //是否创建窗口 
                myProcess.StartInfo.Arguments = "";
                myProcess.StartInfo.RedirectStandardInput = true;  //是否重定向输入
                myProcess.StartInfo.RedirectStandardError = true;   //重定向输出
                myProcess.StartInfo.RedirectStandardOutput = true; //重定向输出
                //myProcess.EnableRaisingEvents = true;
                //myProcess.Exited += myProcess_Exited;
                myProcess.Start();

                myProcess.StandardInput.WriteLine(dosCmd);

                StreamReader errorreader = myProcess.StandardError;

                myProcess.StandardInput.WriteLine("exit");

                myProcess.WaitForExit();

                string result = errorreader.ReadToEnd();
                string output = myProcess.StandardOutput.ReadToEnd();//读取进程的输出  

                return string.IsNullOrEmpty(result) ? output : "Err:" + result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return ex.Message;
            }
        }

        /// <summary>
        /// Ping命令检测网络是否畅通
        /// </summary>
        /// <param name="urls">URL数据</param>
        /// <param name="errorCount">ping时连接失败个数</param>
        /// <returns></returns>
        public static bool NetPing(string[] urls, out int errorCount)
        {
            bool isconn = true;
            Ping ping = new Ping();
            errorCount = 0;
            try
            {
                PingReply pr;
                for (int i = 0; i < urls.Length; i++)
                {
                    pr = ping.Send(urls[i]);
                    if (pr.Status != IPStatus.Success)
                    {
                        isconn = false;
                        errorCount++;
                    }
                    Debug.WriteLine("Ping " + urls[i] + "    " + pr.Status.ToString());
                }
            }
            catch
            {
                isconn = false;
                errorCount = urls.Length;
            }
            //if (errorCount > 0 && errorCount < 3)
            //  isconn = true;
            return isconn;
        }
        /// <summary>
        /// 通过Ping命令获取网络情况
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        public string Ping(string ipAddress)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";           //设置程序名   
            p.StartInfo.UseShellExecute = false;        //关闭shell的使用   
            p.StartInfo.RedirectStandardInput = true;   //重定向标准输入   
            p.StartInfo.RedirectStandardOutput = true;  //重定向标准输出   
            p.StartInfo.RedirectStandardError = true;   //重定向错误输出   
            p.StartInfo.CreateNoWindow = true;          //不显示窗口   
            string pingrst;
            p.Start();
            p.StandardInput.WriteLine("ping -n 2 " + ipAddress);    //-n 1 : 向目标IP发送一次请求   
            p.StandardInput.WriteLine("exit");
            string strRst = p.StandardOutput.ReadToEnd();   //命令执行完后返回结果的所有信息   
            if (strRst.IndexOf("(0% loss)") != -1)
            {
                pingrst = "与目标通路";
            }
            else if (strRst.IndexOf("Destination host unreachable.") != -1)
            {
                pingrst = "无法到达目的主机";
            }
            else if (strRst.IndexOf("Request timed out.") != -1)
            {
                pingrst = "超时";
            }
            else if (strRst.IndexOf("not find") != -1)
            {
                pingrst = "无法解析主机";
            }
            else
            {
                pingrst = strRst;
            }
            p.Close();
            return pingrst;
        }

        /// <summary>
        /// 端口通断校验
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <param name="portNum"></param>
        /// <returns></returns>
        public bool Telnet(string ipAddress, int portNum)
        {
            IPAddress ip = IPAddress.Parse(ipAddress);
            IPEndPoint point = new IPEndPoint(ip, portNum);

            bool _portEnable = false;
            try
            {
                using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    sock.Connect(point);
                    //Console.WriteLine("连接{0}成功!", point);
                    sock.Close();

                    _portEnable = true;
                }
            }
            catch (SocketException e)
            {
                //Console.WriteLine("连接{0}失败", point);
                _portEnable = false;
            }
            return _portEnable;
        }

        /// <summary>
        /// 域名解析
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public Tuple<bool, string> GetDomainIP(string url)
        {
            string ipAddress = url;
            if (!ipAddress.StartsWith("http"))
            {
                ipAddress = "http://" + ipAddress;
            }
            string p = @"(http|https)://(?<domain>[^(:|/]*)";
            Regex reg = new Regex(p, RegexOptions.IgnoreCase);
            Match m = reg.Match(ipAddress);
            try
            {
                string Result = m.Groups["domain"].Value;//提取域名地址 
                IPHostEntry host = Dns.GetHostEntry(Result);//域名解析的IP地址
                IPAddress ip = host.AddressList[0];
                string rIP = ip.ToString();
                return Tuple.Create(true, rIP);
            }
            catch
            {
                return Tuple.Create(false, "请输入正确的域名,或者您的电脑没有联互联网");
            }
        }
    }
}
